/**
 * JMPlurk, a Java Mobile client for Plurk
 * Copyright (C) 2009 Petra Barus
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package com.maleskoding.jmplurk.ui;

import com.maleskoding.jmplurk.JMPlurk;
import com.maleskoding.jmplurk.plurkapi.PlurkAPI;
import com.maleskoding.jmplurk.plurkapi.PlurkException;
import com.maleskoding.jmplurk.ui.components.PlurkTimelineComponent;
import com.maleskoding.jmplurk.util.Preferences;
import com.sun.lwuit.Command;
import com.sun.lwuit.Container;
import com.sun.lwuit.Dialog;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.TabbedPane;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.layouts.BoxLayout;
import java.io.IOException;
import javax.microedition.rms.RecordStoreException;
import org.json.me.JSONException;
import org.json.me.JSONObject;

/**
 *
 * @author Petra Barus
 */
public class MainPlurkForm extends Form implements Runnable, ActionListener {

    private JMPlurk parent;
    //
    public static final int TAB_ALL_PLURKS = 0;
    public static final int TAB_MY_PLURKS = 1;
    public static final int TAB_PRIVATE_PLURKS = 2;
    public static final int TAB_RESPONDED_PLURKS = 3;
    //
    private Command hideCommand;
    private Command newPlurkCommand;
    private Command viewPlurkCommand;
    private Command refreshCommand;
    private Command settingCommand;
    private Command exitCommand;
    //
    private TabbedPane tabbedPane;
    //
    private Container allPlurksPanel;
    private Container myPlurksPanel;
    private Container privatePlurksPanel;
    private Container respondedPlurksPanel;
    private PlurkTimelineComponent allPlurksList;
    private PlurkTimelineComponent myPlurksList;
    private PlurkTimelineComponent privatePlurksList;
    private PlurkTimelineComponent respondedPlurksList;
    //
    private ViewPlurkForm viewPlurkForm;
    //Storing offset for updating purpose
    private String lastUpdated;
    private int timeout;
    private Thread updateThread;
    private boolean isLoggedIn;
    private boolean isUpdating;
    private boolean updateSuspended;
    private boolean updateExists;

    //
    public MainPlurkForm(JMPlurk parent) {
        super("Java Mobile Plurk");
        this.parent = parent;
        init();
        initThread();
        //updateSuspended = false;
        //Thread t = new Thread(this);
        //t.start();
        //TODO: Handle with thread
        //initPlurk();
        //testLogin();
        //updatePlurks();
    }

    //<editor-fold defaultstate="expanded" desc="UI">
    public void init() {
        isLoggedIn = false;
        this.setLayout(new BorderLayout());
        this.setScrollable(false);
        tabbedPane = new TabbedPane(TabbedPane.TOP);

        //Creating all tab components
        //All Plurks Tab
        allPlurksPanel = new Container(new BoxLayout(BoxLayout.Y_AXIS));
        allPlurksList = new PlurkTimelineComponent();
        allPlurksPanel.addComponent(allPlurksList);
        tabbedPane.addTab("All", allPlurksPanel);

        //My Plurks Tab
        myPlurksPanel = new Container(new BoxLayout(BoxLayout.Y_AXIS));
        myPlurksList = new PlurkTimelineComponent();
        myPlurksPanel.addComponent(myPlurksList);
        tabbedPane.addTab("Mine", myPlurksPanel);

        //Private Plurks Tab
        privatePlurksPanel = new Container(new BoxLayout(BoxLayout.Y_AXIS));
        privatePlurksList = new PlurkTimelineComponent();
        privatePlurksPanel.addComponent(privatePlurksList);
        tabbedPane.addTab("Private", privatePlurksPanel);

        //Responded Plurk Tab
        respondedPlurksPanel = new Container(new BoxLayout(BoxLayout.Y_AXIS));
        respondedPlurksList = new PlurkTimelineComponent();
        respondedPlurksPanel.addComponent(respondedPlurksList);
        tabbedPane.addTab("Responded", respondedPlurksPanel);

        //Adding TabbedPane Into Form
        this.addComponent("Center", tabbedPane);

        //Adding Command
        hideCommand = new Command("Hide");
        newPlurkCommand = new Command("New Plurk");
        refreshCommand = new Command("Refresh");
        settingCommand = new Command("Setting");
        exitCommand = new Command("Exit");

        this.addCommand(exitCommand);
        this.addCommand(hideCommand);
        this.addCommand(settingCommand);
        this.addCommand(refreshCommand);
        this.addCommand(newPlurkCommand);
        this.addCommandListener(this);
        viewPlurkForm = new ViewPlurkForm(this);
    }

    private void initThread() {
        updateThread = new Thread(this);
        timeout = 60000;
    }

    /**
     * 
     * @return
     */
    public Command getHideCommand() {
        return hideCommand;
    }

    /**
     * 
     * @return
     */
    public Command getNewPlurkCommand() {
        return newPlurkCommand;
    }

    /**
     * 
     * @return
     */
    public Command getExitCommand() {
        return exitCommand;
    }

    /**
     * 
     * @return
     */
    public Command getViewPlurkCommand() {
        return viewPlurkCommand;
    }

    /**
     * 
     * @return
     */
    public Command getSettingCommand() {
        return settingCommand;
    }

    /**
     *
     */
    public void show() {
        try {
            if (!isLoggedIn) {
                login();
            }
            super.show();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (PlurkException ex) {
            Dialog.show("Error", "Invalid sername or password", "Ok", null);
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (IllegalThreadStateException ex) {
            ex.printStackTrace();
        }
    }

    //</editor-fold>
    //
    //<editor-fold defaultstate="collapsed" desc="Plurk">
    private void login() throws RecordStoreException, PlurkException, IOException {
        Preferences p = Preferences.getInstance();
        JSONObject timeline = JMPlurk.plurk.login(p.get("username"), p.get("password"));
        allPlurksList.appendTimeline(timeline);
        lastUpdated = PlurkAPI.getCurrentTime();
        isLoggedIn = true;
        updateThread.start();
    }

    /**
     * FOR DEBUGGING PURPOSE
     * TODO: Fix this
     */
    public void testLogin() {
//        System.err.println(PlurkAPI.getCurrentTime());
        try {
//            //TODO: Set JMPlurk listener to this
            Preferences p = Preferences.getInstance();
            JSONObject timeline = JMPlurk.plurk.login(p.get("username"), p.get("password"));
            //System.err.println(timeline.toString());
            allPlurksList.appendTimeline(timeline);
//            allPlurksList.setTimeline(timeline);
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (PlurkException ex) {
//            ex.printStackTrace();
        } catch (IOException ex) {
//            ex.printStackTrace();
        }
//        catch (JSONException ex) {
//            ex.printStackTrace();
//        }
    }

    /**
     * 
     */
    private void updatePlurks() {
        //TODO: Handle with thread
        try {
            updateExists = false;
            System.err.println(lastUpdated);
            JSONObject unreadStat = JMPlurk.plurk.getPollingUnreadCount();
            int unreadAllCount = unreadStat.getInt("all");
            tabbedPane.setTabTitle("All (" + unreadAllCount + ")", null, tabbedPane.indexOfComponent(allPlurksPanel));
            int unreadMyCount = unreadStat.getInt("my");
            tabbedPane.setTabTitle("Mine (" + unreadMyCount + ")", null, tabbedPane.indexOfComponent(myPlurksPanel));
            int unreadPrivateCount = unreadStat.getInt("private");
            tabbedPane.setTabTitle("Private (" + unreadPrivateCount + ")", null, tabbedPane.indexOfComponent(privatePlurksPanel));
            int unreadRespondedCount = unreadStat.getInt("responded");
            tabbedPane.setTabTitle("Responded (" + unreadRespondedCount + ")", null, tabbedPane.indexOfComponent(respondedPlurksPanel));
            //
            System.err.println("Unread stat: " + unreadAllCount + " " + unreadMyCount + " " + unreadPrivateCount + " " + unreadRespondedCount);
            updateAllPlurks();
            lastUpdated = PlurkAPI.getCurrentTime();
            //        updateUnreadPlurks();
            //        updateRespondedPlurks();
            //        updateRespondedPlurks();
        } catch (PlurkException ex) {
            ex.printStackTrace();
        } catch (JSONException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Loading all plurks
     */
    private void updateAllPlurks() {
        try {
            System.err.println("updateAllPlurks");
//            //TODO: Set JMPlurk listener to this
            JSONObject timeline = JMPlurk.plurk.getPollingPlurks(lastUpdated);
            System.out.println(timeline);
            allPlurksList.appendTimeline(timeline);
        } catch (PlurkException ex) {
            ex.printStackTrace();
        } catch (JSONException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void setAllPlurksTimeline(JSONObject timeline) throws JSONException {
//        allPlurksList.setTimeline(timeline);
    }

    /**
     * Loading all plurks
     */
//    private void updateUnreadPlurks() {
//        try {
//            System.err.println("updateUnreadPlurks");
//            //TODO: Set JMPlurk listener to this
//            JSONObject timeline = JMPlurk.plurk.getUnreadPlurks(lastUpdated);
//            System.err.println(timeline);
//            unreadPlurksList.clearTimeline();
//            unreadPlurksList.appendTimeline(timeline);
//        } catch (PlurkException ex) {
//            ex.printStackTrace();
//        } catch (JSONException ex) {
//            ex.printStackTrace();
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }
//    }
    /**
     * Loading my plurks
     */
//    private void updateMyPlurks() {
//        try {
//            //TODO: Set JMPlurk listener to this
//            System.err.println("updateMyPlurks");
//            JSONObject timeline = JMPlurk.plurk.getMyPlurks(lastUpdated);
//            System.err.println(timeline);
//            myPlurksList.appendTimeline(timeline);
//        } catch (PlurkException ex) {
//            ex.printStackTrace();
//        } catch (JSONException ex) {
//            ex.printStackTrace();
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }
//    }
    /**
     * Loading responded plurks
     */
//    private void updateRespondedPlurks() {
//        try {
//            System.err.println("updateRespondedPlurks");
////            TODO: Set JMPlurk listener to this
//            JSONObject timeline = JMPlurk.plurk.getRespondedPlurks(lastUpdated);
//            System.err.println(timeline);
//            respondedPlurksList.appendTimeline(timeline);
//        } catch (PlurkException ex) {
////            ex.printStackTrace();
//        } catch (JSONException ex) {
////            ex.printStackTrace();
//        } catch (IOException ex) {
////            ex.printStackTrace();
//        }
//    }
    /**
     * Get ID from selected plurk in the tabbedPane
     * @return selected ID
     */
    public String getSelectedPlurkId() {
        String[] item = new String[4];
        switch (tabbedPane.getSelectedIndex()) {
            case TAB_ALL_PLURKS:
                return allPlurksList.getSelectedPlurkID();
            case TAB_MY_PLURKS:
                return myPlurksList.getSelectedPlurkID();
            case TAB_RESPONDED_PLURKS:
                return respondedPlurksList.getSelectedPlurkID();
            case TAB_PRIVATE_PLURKS:
                return privatePlurksList.getSelectedPlurkID();
        }
        return item[0];
    }

    /**
     * Handle fire key event
     * @param keyCode
     */
    public void keyPressed(int keyCode) {
        super.keyPressed(keyCode);
        int game = Display.getInstance().getGameAction(keyCode);
        if (game == Display.GAME_FIRE) {
            String plurkID = getSelectedPlurkId();
            if (plurkID.length() > 0) {
                viewPlurkForm.loadPlurk(plurkID);
                viewPlurkForm.show();
            }
        }
    }
    //</editor-fold>

    /**
     * 
     */
    public void refreshPlurk() {
        //TODO: Thread locking
        if (!isUpdating) {
            updatePlurks();
        }
    }

    /**
     * 
     */
    public void run() {
        while (!updateSuspended) {
            //TODO: Thread locking
            isUpdating = true;
            System.err.println("Updating");
            updatePlurks();
            isUpdating = false;
            try {
                Thread.sleep(timeout);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void actionPerformed(ActionEvent ae) {
        Command command = ae.getCommand();
        if (command == settingCommand) {
            parent.getSettingForm().show();
        } else if (command == exitCommand) {
            parent.exitMIDlet();
        } else if (command == newPlurkCommand) {
            parent.getNewPlurkForm().show();
        }
    }
}
